package com.centling.smartSealForPhone.service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.widget.RemoteViews;

import com.centling.smartSealForPhone.R;
import com.centling.smartSealForPhone.constants.UrlConstants;
import com.centling.smartSealForPhone.db.DbControl;
import com.centling.smartSealForPhone.db.ImageBean;
import com.centling.smartSealForPhone.utils.LogUtil;
import com.centling.smartSealForPhone.utils.OkHttpUtil;

import java.util.List;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * 开启上传图片Service
 *
 * @author fionera
 */
public class UploadImageService
        extends Service {
    public static final String ACTION_NOTIFICATION_CLICK = "com.example.ACTION_NOTIFICATION_CLICK";

    private NotificationManager notificationManager;
    private Notification notification;
    private final static int NOTIFICATION_ID = 19172439;

    private Disposable disposable;
    private boolean isUploading = false;
    private int failedCount = 0;

    private BroadcastReceiver onClickReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (TextUtils.equals(intent.getAction(), ACTION_NOTIFICATION_CLICK)) {
                startService(new Intent(UploadImageService.this, UploadImageService.class));
            }
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_NOTIFICATION_CLICK);
        registerReceiver(onClickReceiver, filter);
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        ConnectivityManager mConnectivityManager = (ConnectivityManager) UploadImageService.this
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (mConnectivityManager == null) {
            return super.onStartCommand(intent, flags, startId);
        }
        NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
        if (mNetworkInfo == null) {
            return super.onStartCommand(intent, flags, startId);
        }
        if (!mNetworkInfo.isAvailable() || isUploading) {
            return super.onStartCommand(intent, flags, startId);
        }

        notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        
        isUploading = true;

        startUploadProcess();

        return super.onStartCommand(intent, flags, startId);
    }

    private void startUploadProcess() {
        disposable = Flowable.create(new FlowableOnSubscribe<List<ImageBean>>() {
            @Override
            public void subscribe(FlowableEmitter<List<ImageBean>> e) throws Exception {
                e.onNext(DbControl.getInstance().selectAll());
                e.onComplete();
            }
        }, BackpressureStrategy.BUFFER).subscribeOn(Schedulers.io()).subscribe(new Consumer<List<ImageBean>>() {
            @Override
            public void accept(final List<ImageBean> images) throws Exception {
                isUploading = images.size() > 0;
                if (images.size() > 0) {
                    initNotification();
                    isUploading = true;
                }
                OkHttpUtil.count = 0;

                if (images.size() > 0) {
                    for (int j = 0; j < images.size(); j++) {
                        final int finalJ = j;
                        if (j > OkHttpUtil.count) {
                            j--;
                        } else {
//                            System.out.println(images.get(j).getFileName());
                            LogUtil.d("---文件名："+images.get(j).getFileName());
                            OkHttpUtil.postEnqueueUploadByFile(images, images.get(j),
                                    UrlConstants.ROOTURL + UrlConstants.UPLOAD_PIC,
                                    images.get(j).getName(), images.get(j).getFileName(),
                                    images.get(j).getPaths(), new OkHttpUtil.NetCallBack() {
                                        @Override
                                        public void onSucceed(String json) {
                                            DbControl.getInstance().deleteData(
                                                    images.get(finalJ).getId());
                                            LogUtil.e("picture upload success");
                                            images.get(finalJ).recycle();
                                        }

                                        @Override
                                        public void onFailed(String reason) {
                                            LogUtil.e("picture upload failed:" + reason);
                                            images.get(finalJ).recycle();
                                            failedCount++;
                                        }
                                    }, new OkHttpUtil.NetProgressCallback() {
                                        @Override
                                        public void progress(float process) {
                                            if (process == 1.0) {
                                                isUploading = false;
                                                if (failedCount > 0) {
                                                    initFailNotification(failedCount);
                                                    showNotification();
                                                    return;
                                                }
                                            }
                                            LogUtil.e("picture upload process:" + process);
                                            notification.contentView.setProgressBar(
                                                    R.id.pb_notification_process, 100,
                                                    (int) (100 * process), false);
                                            showNotification();
                                            if (process >= 1.0) {
                                                isUploading = false;
                                                notificationManager.cancel(NOTIFICATION_ID);
                                            }
                                        }
                                    });
                        }
                    }
                }
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Exception {
                throwable.printStackTrace();
            }
        });
    }

    private void initNotification() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
                "DEFAULT_CHANNEL");
        Drawable d = ContextCompat.getDrawable(this, R.mipmap.ic_launcher);
        BitmapDrawable bitmapDrawable = (BitmapDrawable) d;
        Bitmap bitmap = bitmapDrawable.getBitmap();
        builder.setLargeIcon(bitmap).setTicker("图片正在上传中").setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("上传图片").setContent(
                new RemoteViews(getPackageName(), R.layout.layout_notification));
        builder.setSmallIcon(R.mipmap.ic_launcher);

        notification = builder.build();
    }

    private void initFailNotification(int count) {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
                "DEFAULT_CHANNEL");
        Intent buttonIntent = new Intent(ACTION_NOTIFICATION_CLICK);

        PendingIntent pendButtonIntent = PendingIntent.getBroadcast(this, 0, buttonIntent, 0);
        RemoteViews mRemoteViews = new RemoteViews(getPackageName(), R.layout.notification_upload);
        mRemoteViews.setOnClickPendingIntent(R.id.tv_continue, pendButtonIntent);
        mRemoteViews.setTextViewText(R.id.tv_notification, "有" + count + "张图片上传失败");
        builder.setContent(mRemoteViews);
        builder.setSmallIcon(R.mipmap.ic_launcher);

        notification = builder.build();
    }

    public void showNotification() {
        notificationManager.notify(NOTIFICATION_ID, notification);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(onClickReceiver);
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }
}
